package io.sundial.coordination.curator;

import io.sundial.core.Delegation;
import org.apache.curator.CuratorZookeeperClient;
import org.apache.curator.RetryPolicy;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.framework.AuthInfo;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.*;
import org.apache.curator.framework.api.transaction.CuratorTransaction;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.framework.listen.Listenable;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.utils.EnsurePath;
import org.apache.curator.utils.ZookeeperFactory;
import org.apache.zookeeper.Watcher;

import java.util.List;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * Curator 建造者
 *
 * @author Payne 646742615@qq.com
 * 2018/12/22 21:37
 */
public class CuratorDelegation extends Delegation<CuratorFramework> implements CuratorFramework {
    private final CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();

    @Override
    protected CuratorFramework build() {
        CuratorFramework curator = builder.build();
        curator.start();
        return curator;
    }

    // -------------------------------- delegate ---------------------------

    public void start() {
        get().start();
    }

    public void close() {
        get().close();
    }

    public CuratorFrameworkState getState() {
        return get().getState();
    }

    @Deprecated
    public boolean isStarted() {
        return get().isStarted();
    }

    public CreateBuilder create() {
        return get().create();
    }

    public DeleteBuilder delete() {
        return get().delete();
    }

    public ExistsBuilder checkExists() {
        return get().checkExists();
    }

    public GetDataBuilder getData() {
        return get().getData();
    }

    public SetDataBuilder setData() {
        return get().setData();
    }

    public GetChildrenBuilder getChildren() {
        return get().getChildren();
    }

    public GetACLBuilder getACL() {
        return get().getACL();
    }

    public SetACLBuilder setACL() {
        return get().setACL();
    }

    public CuratorTransaction inTransaction() {
        return get().inTransaction();
    }

    @Deprecated
    public void sync(String path, Object backgroundContextObject) {
        get().sync(path, backgroundContextObject);
    }

    public void createContainers(String path) throws Exception {
        get().createContainers(path);
    }

    public SyncBuilder sync() {
        return get().sync();
    }

    public Listenable<ConnectionStateListener> getConnectionStateListenable() {
        return get().getConnectionStateListenable();
    }

    public Listenable<CuratorListener> getCuratorListenable() {
        return get().getCuratorListenable();
    }

    public Listenable<UnhandledErrorListener> getUnhandledErrorListenable() {
        return get().getUnhandledErrorListenable();
    }

    @Deprecated
    public CuratorFramework nonNamespaceView() {
        return get().nonNamespaceView();
    }

    public CuratorFramework usingNamespace(String newNamespace) {
        return get().usingNamespace(newNamespace);
    }

    public String getNamespace() {
        return get().getNamespace();
    }

    public CuratorZookeeperClient getZookeeperClient() {
        return get().getZookeeperClient();
    }

    @Deprecated
    public EnsurePath newNamespaceAwareEnsurePath(String path) {
        return get().newNamespaceAwareEnsurePath(path);
    }

    public void clearWatcherReferences(Watcher watcher) {
        get().clearWatcherReferences(watcher);
    }

    public boolean blockUntilConnected(int maxWaitTime, TimeUnit units) throws InterruptedException {
        return get().blockUntilConnected(maxWaitTime, units);
    }

    public void blockUntilConnected() throws InterruptedException {
        get().blockUntilConnected();
    }

    // ------------------------------------- builder ------------------------------------

    public void setConnectString(String connectString) {
        builder.connectString(connectString);
    }

    public void setEnsembleProvider(EnsembleProvider ensembleProvider) {
        builder.ensembleProvider(ensembleProvider);
    }

    public void setSessionTimeoutMs(int sessionTimeoutMs) {
        builder.sessionTimeoutMs(sessionTimeoutMs);
    }

    public void setConnectionTimeoutMs(int connectionTimeoutMs) {
        builder.connectionTimeoutMs(connectionTimeoutMs);
    }

    public void setMaxCloseWaitMs(int maxCloseWaitMs) {
        builder.maxCloseWaitMs(maxCloseWaitMs);
    }

    public void setRetryPolicy(RetryPolicy retryPolicy) {
        builder.retryPolicy(retryPolicy);
    }

    public void setThreadFactory(ThreadFactory threadFactory) {
        builder.threadFactory(threadFactory);
    }

    public void setNamespace(String namespace) {
        builder.namespace(namespace);
    }

    public void setAuthInfos(List<AuthInfo> authInfos) {
        builder.authorization(authInfos);
    }

    public void setDefaultData(byte[] defaultData) {
        builder.defaultData(defaultData);
    }

    public void setCompressionProvider(CompressionProvider compressionProvider) {
        builder.compressionProvider(compressionProvider);
    }

    public void setZookeeperFactory(ZookeeperFactory zookeeperFactory) {
        builder.zookeeperFactory(zookeeperFactory);
    }

    public void setAclProvider(ACLProvider aclProvider) {
        builder.aclProvider(aclProvider);
    }

    public void setCanBeReadOnly(boolean canBeReadOnly) {
        builder.canBeReadOnly(canBeReadOnly);
    }

    public void setUseContainerParentsIfAvailable(boolean useContainerParentsIfAvailable) {
        if (useContainerParentsIfAvailable) {
            builder.useContainerParentsIfAvailable();
        } else {
            builder.dontUseContainerParents();
        }
    }
}
